package com.atmilan.quartz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.dto.efasion.EfasionProductResDTO;
import com.atmilan.quartz.model.dto.efasion.EfasionProductResDTO.Product;
import com.atmilan.quartz.model.dto.efasion.EfasionProductResDTO.ProductSku;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.efasion.EfasionProduct;
import com.atmilan.quartz.model.entity.efasion.EfasionProductSku;
import com.atmilan.quartz.service.IEfasionProductService;
import com.atmilan.quartz.service.IEfasionProductSkuService;
import com.atmilan.quartz.service.IEfasionSyncService;
import com.atmilan.quartz.service.IStoreProductAttrService;
import com.atmilan.quartz.service.IStoreProductAttrValueService;
import com.atmilan.quartz.service.IStoreProductNormService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.utils.ImageSearchUtils;
import com.atmilan.quartz.utils.OSSUtil;
import com.atmilan.quartz.utils.RedisUtil;
import com.atmilan.quartz.utils.product.EfasionProductUtil;
import com.atmilan.quartz.utils.source.SourceEfasionProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class EfasionSyncServiceImpl implements IEfasionSyncService {
    @Autowired
    OSSUtil ossUtil;
    @Autowired
    IEfasionProductService efasionProductService;
    @Autowired
    IEfasionProductSkuService efasionProductSkuService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    IStoreProductNormService storeProductNormService;
    @Autowired
    IStoreProductAttrService storeProductAttrService;
    @Autowired
    IStoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    SourceEfasionProductUtil sourceEfasionProductUtil;
    @Autowired
    EfasionProductUtil efasionProductUtil;

    /**
     * 分页查询商品
     */
    @Override
    public Boolean syncProduct() {
        // 数据清空
        efasionProductService.deleteAll();
        efasionProductSkuService.deleteAll();
        // 分页信息
        int pageNo = 1;
        int pageSize = 100;
        int pageCount = 1;

        long millis = System.currentTimeMillis();
        // 循环获取商品数据并保存
        while (pageNo <= pageCount) {
            try {
                EfasionProductResDTO resDTO = efasionProductUtil.selectProductPage(pageNo, pageSize);
                // 到达末页
                if (null == resDTO || CollectionUtils.isEmpty(resDTO.getProduct())) {
                    pageNo++;
                    continue;
                }
                pageCount = (resDTO.getCount() + pageSize - 1) / pageSize;
                // 处理数据保存
                List<Product> goodsList = resDTO.getProduct();
                // 商品保存
                saveGoods(goodsList);
                
                log.info("--------------- efasion远程抓取数据, 第: {} 页, 总共: {} 页, 总耗时: {} 分  ---------------", pageNo, pageCount, (int)((System.currentTimeMillis() - millis) / 1000 / 60));
            } catch (Exception e) {
                e.printStackTrace();
            }

            pageNo++;
        }
        
        return true;
    }
    
    // 商品源数据保存
    private void saveGoods(List<Product> goodsList) {
        // 商品数据
        List<EfasionProduct> goodsEntity = new ArrayList<>();
        List<EfasionProductSku> goodsSkuEntity = new ArrayList<>();
        for(Product goods : goodsList) {
        	// 商品
        	EfasionProduct productEntity = new EfasionProduct();
            BeanUtils.copyProperties(goods, productEntity);
            goodsEntity.add(productEntity);
            
            // sku
            List<ProductSku> skus = goods.getSkus();
            if(CollectionUtils.isNotEmpty(skus)) {
            	List<EfasionProductSku> goodsSkus = JSONArray.parseArray(JSON.toJSONString(skus), EfasionProductSku.class);
            	goodsSkuEntity.addAll(goodsSkus);
            }
        }
        
        efasionProductService.saveBatch(goodsEntity);
        efasionProductSkuService.saveBatch(goodsSkuEntity);
    }
    

    /**
     * 下发商品
     */
	@Override
	public Boolean pushProduct() {
	    // 当次更新少于3000条, 则不更新, 并且重新拉取
		int count = efasionProductService.count();
		/*if (3000 > count) {
		    systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
		            .eq(SystemConfig::getName, Constants.EFASION_SYNC_STATUS)
		            .set(SystemConfig::getFormId, SyncStatusEnum.PUSH)
		            .set(SystemConfig::getUpdateTime, new Date()));
		    log.info("--------------- EFASION商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
		    return false;
		}*/
	
	    // 将所有商品更新状态置为未更新
	    storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
	            .eq(StoreProduct::getIsEurope, ProductTypeEnum.EFASION.getCode())
	            .set(StoreProduct::getUpdateFlag, false)
	            );
	
	    // 商品更新操作
	    int pageNo = 1;
	    int pageSize = 100;
	    int maxPage = (count + pageSize - 1) / pageSize;
	    log.info("--------------- 开始分页查询efasion商品源数据, 本次更新总条数为: {} ---------------", count);
	
	    long millis = System.currentTimeMillis();
	    while (pageNo <= maxPage) {
	        try {
	            PageHelper.startPage(pageNo, pageSize);
	            List<EfasionProduct> efasionProducts = efasionProductService.list();
	            PageInfo<EfasionProduct> pageInfo = PageInfo.of(efasionProducts);
	            List<EfasionProduct> products = pageInfo.getList();
	            buildProduct(products);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	
	        log.info("--------------- efasion下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int)((System.currentTimeMillis() - millis) / 1000 / 60));
	        pageNo++;
	    }
	    // 删除图搜商品
	    List<StoreProduct> storeProductBarcodes = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery()
	            .eq(StoreProduct::getIsEurope, ProductTypeEnum.EFASION.getCode())
	            .eq(StoreProduct::getUpdateFlag, false)
	            .eq(StoreProduct::getIsTusou, false)
	            .select(StoreProduct :: getBarCode)
	            );
	    log.info("--------------- efasion待下架商品总数: {} ---------------", storeProductBarcodes.size());
	    for(StoreProduct storeProduct : storeProductBarcodes) {
	        try {
	            ImageSearchUtils.deleteImage(storeProduct.getBarCode(), null);
	            log.info("--------------- efasion删除图搜数据: {} ---------------", storeProduct.getBarCode());
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
	
	    // 下架所有未更新数据
	    storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
	            .eq(StoreProduct::getIsEurope, ProductTypeEnum.EFASION.getCode())
	            .eq(StoreProduct::getUpdateFlag, false)
	            .eq(StoreProduct :: getIsShow, true)
	            .eq(StoreProduct :: getIsDel, false)
	            .set(StoreProduct::getIsShow, false)
	            .set(StoreProduct::getStock, 0)
	            .set(StoreProduct::getLastPushTime, new Date())
	            .set(StoreProduct::getIsTusou, false)
	            );
	    // 下架所有sku库存
	    storeProductService.downloadSku(ProductTypeEnum.EFASION.getCode());
	
	    return true;
	}

    /**
     * 商品构建处理
     * @Description:  
     * @author daigb 
     * @param @param products
     * @return void
     * @throws
     */
    private void buildProduct(List<EfasionProduct> products) {
        try {
            for (EfasionProduct product : products) {
                List<EfasionProductSku> skus = efasionProductSkuService.list(Wrappers.<EfasionProductSku>lambdaQuery()
                        .eq(EfasionProductSku :: getProductId, product.getProductId())
                        .gt(EfasionProductSku :: getStock, 0)
                        );
                if (CollectionUtils.isEmpty(skus) || StringUtils.isBlank(product.getStoreName())) {
                    continue;
                }
                // 库存计算
                int stock = 0;
                for (EfasionProductSku sku : skus) {
                    stock += sku.getStock();
                }

                // 构建实体
                if(2214455 == product.getProductId()) {
                	System.out.println("1");
                }
                StoreProductCrmebRequest storeProductCrmebRequest = sourceEfasionProductUtil.buildProduct(product, skus);
                // 数据保存
                StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode(), storeProductCrmebRequest.getSuppliersId(), storeProductCrmebRequest.getKeyword());
                boolean crmebUpdate = true;
                if (null != storeProduct && null != storeProduct.getLastPushTime()) {
                    long time = (System.currentTimeMillis() - storeProduct.getLastPushTime().getTime()) / 1000 / 60;
                    if (60 > time) {
                        log.info("--------------- 该商品: {} 上次更新时间: {} 小于一小时, 不进行更新 ---------------", storeProductCrmebRequest.getBarCode(), storeProduct.getLastPushTime());
                        crmebUpdate = false;
                        storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                                .eq(StoreProduct::getId, storeProduct.getId())
                                .set(StoreProduct::getUpdateFlag, true)
                                );
                    }
                }
                if (crmebUpdate) {
                    storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
